package com.miyake.dsp.ui;

import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.miyake.dsp.ComplexArray;
import com.miyake.dsp.DspComposite;
import com.miyake.dsp.DspComposite.DspCompositeHandler;
import com.miyake.dsp.Processor;
import com.miyake.dsp.ui.DspWidget.DspWidgetHandler;

public class DspCompositeUI {
	public interface DspCompositeUiHandler {
		void onAdd(DspCompositeUI ui);
	};
	private List<DspCompositeUiHandler> uiHandlers = new ArrayList<DspCompositeUiHandler>();
	public void addUiHandler(DspCompositeUiHandler uiHandler) {
		uiHandlers.add(uiHandler);
	}
	private void fireAdd(DspCompositeUI ui) {
		for (DspCompositeUiHandler h : uiHandlers) {
			h.onAdd(ui);
		}
	}
	
	private DspWidget panel;
	private JFrame chartFrame;
	private JFrame settingFrame;
	private LineChartPanel chart;
	private JPanel subContainer = new JPanel();

	private DspComposite composite;
	
	public DspCompositeUI(Processor processor, DspWidget panel) {
		composite = new DspComposite(processor);
		composite.setUserObject(this);
		this.panel = panel;
		initialize();
		
		if (panel != null) {
			panel.addHandler(new DspWidgetHandler() {
				@Override
				public void onChange(String value) {
					composite.run();
				}
			});
		}
		
	}

	private void initialize() {
		JButton button = new JButton(composite.getProcessor().getClass().getSimpleName());
		button.setSize(100, 40);
		button.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				setChartVisible(true);
			}
		});
		
		JButton settingButton = new JButton("Setting");
		settingButton.setSize(100, 16);
		settingButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				setSettingVisible(true);
			}
		});
		if (panel == null) {
			settingButton.setEnabled(false);
		}
		
		final JCheckBox check = new JCheckBox("Bypass");
		check.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				composite.setBypass(check.isSelected());
				composite.run();
			}
		});
		
		subContainer.setLayout(new GridLayout(1,3));
		subContainer.add(button);
		JPanel p = new JPanel();
		p.add(check);
		p.add(settingButton);
		
		JButton addButton = new JButton("Add");
		addButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				fireAdd();
			}
		});
		p.add(addButton);
		subContainer.add(p);
		subContainer.setSize(500, 35);
		subContainer.setForeground(Color.red);
	}

	protected void fireAdd() {
		fireAdd(this);
	}
	
	private LineChartPanel createChart() {
		if (chart == null) {
			chart = new LineChartPanel(composite.getProcessor().getClass().getSimpleName());
			composite.addHandler(new DspCompositeHandler() {
				@Override
				public void onRun() {
					updateChart();
				}
			});
		}
		return chart;
	}

	public void setSettingVisible(boolean b) {
		if (settingFrame == null) {
			settingFrame = new JFrame();
			settingFrame.setTitle(panel.getName());
			settingFrame.getContentPane().add(panel);
			settingFrame.setSize(500, 200);
		}
		settingFrame.setVisible(b);
	}
	
	
	public void setChartVisible(boolean b) {
		if (chartFrame == null) {
			chartFrame = new JFrame();
			chartFrame.getContentPane().add(createChart());
			chartFrame.setSize(400, 300);
		}
		chartFrame.setVisible(b);
		updateChart();
	}

	private void updateChart() {
		chart.removeAllTrace();
		ComplexArray ret = composite.getLatestData();
		if (ret == null) {
			return;
		}
		chart.setData("Real Part", ret.getRealPart());
		chart.setData("Imaginary Part", ret.getImagPart());
	}
	
	public LineChartPanel getChart() {
		return createChart();
	}
	
	public void layout(Container container, int x, int y) {
		container.add(subContainer);
		subContainer.setLocation(x, y);
		for (DspComposite c : composite.getList()) {
			((DspCompositeUI)c.getUserObject()).layout(container, x, y + subContainer.getHeight());
		}
	}

	public DspWidget getPanel() {
		return panel;
	}

	public DspComposite getComposite() {
		return composite;
	}

	public void setComposite(DspComposite composite) {
		this.composite = composite;
	}

	public void add(DspCompositeUI ui) {
		composite.add(ui.getComposite());
	}

	public void run() {
		composite.run();
	}
	
	public List<DspComposite> getCompositeList() {
		return composite.getList();
	}
	
	public void remove(DspCompositeUI ui) {
		composite.remove(ui.getComposite());
	}
	public void clear() {
		composite.clear();
	}
	
}
